﻿using RBAC.Domain;
using RBAC.Server.Interface;
using Sowrk03_28.Repository;
using Sowrk03_28.Repository.Interface;
using Swork03_28.Domain.RBAC;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RBAC.Server.Impls
{
    public class MenuServer : IMenuServer
    {
        private readonly IMenuRepository _MenuInfo;
        private readonly IRepository<Roles> _Roles;
        private readonly IRepository<RoleMenuDetail> _RoleMenuDetail;

        public MenuServer(IMenuRepository menuInfo,
            IRepository<Roles> Roles,
            IRepository<RoleMenuDetail> RoleMenuDetail
            )
        {
            _MenuInfo = menuInfo;
            _Roles = Roles;
            _RoleMenuDetail = RoleMenuDetail;
        }

        public async Task<int> MenuAdd(MenuInfo menuInfo)
        {
            if (_MenuInfo.GetValues(x => x.Name == menuInfo.Name && x.Pid == menuInfo.Pid).Result.Count() > 0)
            {
                //同一父编号下名称不能相同
                return -1;
            }
            if (menuInfo.Pid == 0)
            {
                menuInfo.PName = "顶级菜单";
            }
            else
            {
                menuInfo.PName = _MenuInfo.GetAsync(menuInfo.Pid).Result.Name;
            }
            menuInfo.CreatePeople = "张三";
            menuInfo.CreateTime = DateTime.Now;
            menuInfo.UpdatePeople = null;
            menuInfo.UpdateTime = null;

            await _MenuInfo.CreateAsync(menuInfo);
            return 1;
        }

        public List<MenuItem> GetMenuItems(int pid)
        {
            var res = _MenuInfo.GetValues(x => x.Pid == pid).Result.ToArray().Select(x => new MenuItem
            {
                label = x.Name,
                value = x.Id,
                children = GetMenuItems(x.Id).Count > 0 ? GetMenuItems(x.Id) : null
            }).ToList();
            return res;
        }

        public async Task<(int totalCount, int pageCount, List<MenuInfo> list)> GetMenuInfos(int pageIndex, int pageSize)
        {
            var info = await _MenuInfo.AllAsync();
            var res = new List<MenuInfo>();

            foreach (var item in info)
            {
                var pname = "";
                if (item.Pid == 0)
                {
                    pname = item.PName;
                }
                else
                {
                    pname = item.Name + "=>" + item.PName;
                }
                res.Add(new MenuInfo
                {
                    Name = item.Name,
                    Pid = item.Pid,
                    CreatePeople = item.CreatePeople,
                    CreateTime = item.CreateTime,
                    Id = item.Id,
                    OrderNum = item.OrderNum,
                    PName = pname,
                    UpdatePeople = item.UpdatePeople,
                    UpdateTime = item.UpdateTime,
                    Url = item.Url,
                });
            }
            int totalCount = res.Count();
            int pageCount = (int)Math.Ceiling(totalCount * 1.0 / pageSize);
            res = res.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
            return (totalCount, pageCount, res);
        }

        public async Task<object> Del(int id)
        {
            var info = await _MenuInfo.GetAsync(id);
            var count = 0;
            if ((await _MenuInfo.GetValues(x => x.Pid == info.Id)).Count() > 0)
            {
                var res = _MenuInfo.GetValues(x => x.Pid == info.Id).Result.Select(x => x.Id);
                var res1 = _MenuInfo.GetValues(x => res.Contains(x.Pid)).Result.Select(x => x.Id);
                return res.Concat(res1);
            }
            var del = _RoleMenuDetail.GetValues(x => x.MenuId == id).Result.FirstOrDefault();
            if (del == null)
            {
                count += await _MenuInfo.DeleteAsync(info);
                return count;
            }
            count += await _RoleMenuDetail.DeleteAsync(del);
            count += await _MenuInfo.DeleteAsync(info);
            return count;
        }

        public async Task<int> DelMuch(List<int>? ids)
        {
            var res = new List<MenuInfo>();
            var info = _MenuInfo.GetValues(x => ids.Contains(x.Id)).Result.ToArray();
            var del = _RoleMenuDetail.GetValues(x => ids.Contains(x.MenuId)).Result.ToList();
            if (del == null)
            {
                _MenuInfo.DeleteAllAsync(info.ToList());
            }
            _RoleMenuDetail.DeleteAllAsync(del);
            _MenuInfo.DeleteAllAsync(info.ToList());
            return 1;
        }

        public async Task<MenuInfo> GetMenu(int id)
        {
            return await _MenuInfo.GetAsync(id);
        }

        public async Task<int> Update(MenuInfo info)
        {
            if (_MenuInfo.GetValues(x => x.Name == info.Name && x.Pid == info.Pid && x.Id != info.Id).Result.Count() > 0)
            {
                //同一父编号下名称不能相同
                return -1;
            }
            if (info.Pid == 0)
            {
                info.PName = "顶级菜单";
            }
            else
            {
                info.PName = _MenuInfo.GetAsync(info.Pid).Result.Name;
            }
            info.UpdatePeople = "李四";
            info.UpdateTime = DateTime.Now;
            await _MenuInfo.UpdateAsync(info);
            return 1;
        }

        public List<MenuItem> GetMenuTree(int pId, string? name)
        {
            var info = _MenuInfo.GetValues(x => x.Pid == pId).Result.ToArray();
            if (name != null)
            {
                info = info.Where(x => x.Name.Contains(name)).ToArray();
            }
            var res = info.Select(x => new MenuItem
            {
                label = x.Name,
                value = x.Id,
                children = GetMenuTree(x.Id, name).Count() > 0 ? GetMenuTree(x.Id, name) : null

            });
            return res.ToList();
        }

        public async Task<List<MenuItem>> GetRoleTree(string? name)
        {
            var info = _Roles.AllAsync().Result.ToArray();
            if (name != null)
            {
                info = info.Where(x => x.Name.Contains(name)).ToArray();
            }
            var res = info.Select(x => new MenuItem
            {
                label = x.Name,
                value = x.Id,

            });
            return res.ToList();
        }

        public async Task<List<int>> MenuTreeIds(int Rid)
        {
            var info = _RoleMenuDetail.GetValues(x => x.RoleId == Rid).Result.Select(x => x.MenuId).ToList();
            return info;
        }

        public async Task<int> RoleMenuAdd(int Rid, List<int> MenuId)
        {
            var count = 0;
            var del = await _RoleMenuDetail.GetValues(x => x.RoleId == Rid);
            count += await _RoleMenuDetail.DeleteAllAsync(del.ToList());
            foreach (var item in MenuId)
            {
                var info = new RoleMenuDetail
                {
                    RoleId = Rid,
                    MenuId = item,
                };

                count += await _RoleMenuDetail.CreateAsync(info);
            }
            return count;
        }
    }
}
